// VocoderGUI.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "../Vocoder/Settings.h" 
#include "../Vocoder/Vocoder.h"
#include "../Vocoder/PerformanceMonitor.h"
#include "../Vocoder/PitchTracker.h"
#include "../Vocoder/SequencedFrequencyProvider.h"
#include "../Vocoder/RandomFrequencyProvider.h"
#include "../Vocoder/SoundBank.h"
#include "../Vocoder/Scale.h"
#include "../Vocoder/CarrierImpl.h"
#include "../Vocoder/ModulatorImpl.h"
#include "../Vocoder/Overlapper.h"
#include "../Vocoder/OverlappingModulator.h"
#include "../Vocoder/OverlappingCarrier.h"
#include "../SFMLAdapter/Recorder.h"

#include "VocoderGUI.h"
#include "VocoderGUIDlg.h"
#include "VocoderController.h"
#include "SAPIModulator.h"
#include "VocoderThread.h"
#include "PlayerThread.h"

#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#endif


// CVocoderGUIApp

BEGIN_MESSAGE_MAP(CVocoderGUIApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CVocoderGUIApp construction

CVocoderGUIApp::CVocoderGUIApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CVocoderGUIApp object

CVocoderGUIApp theApp;


// CVocoderGUIApp initialization

void ReadSettings(Settings* settings)
{
	settings->samplingRate = 48000;
	settings->windowLength = 1024;
	settings->overlapLength = 0;
}


INT_PTR CVocoderGUIApp::RunVocoder()
{
	//don't want to detect memory leaks until objects are out of scope	
	::CoInitialize(NULL);

	// InitCommonControlsEx() is required on Windows XP if an application
	// manifest specifies use of ComCtl32.dll version 6 or later to enable
	// visual styles.  Otherwise, any window creation will fail.
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// Set this to include all the common control classes you want to use
	// in your application.
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);

	CWinApp::InitInstance();

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	// of your final executable, you should remove from the following
	// the specific initialization routines you do not need
	// Change the registry key under which our settings are stored
	// TODO: You should modify this string to be something appropriate
	// such as the name of your company or organization
	SetRegistryKey(_T("Local AppWizard-Generated Applications"));

	Vocoder vocoder;
	ReadSettings(vocoder.GetSettings());
	int SAMPLE_RATE = vocoder.GetSettings()->samplingRate;//48000;
	int WINDOW_LENGTH = vocoder.GetSettings()->windowLength;//1024;
	int OVERLAP_LENGTH = vocoder.GetSettings()->overlapLength;

	PerformanceMonitor performance;
	Recorder recorder;
	recorder.isListening = false;
	

	PitchTracker pitchTracker(WINDOW_LENGTH, SAMPLE_RATE);
	SequencedFrequencyProvider seqProvider;
	RandomFrequencyProvider randProvider(220, 440, 10, 30);
	
	SoundBank soundBank(SAMPLE_RATE);
	Scale scale;
	//scale.SetChromatic();
	scale.SetAMinor();


	CarrierImpl carrier;
	carrier.SetFrequencyProvider(&pitchTracker);
	//carrier.SetFrequencyProvider(&seqProvider);
	//carrier.SetFrequencyProvider(&randProvider);
	//carrier.SetVocoderListener(&recorder);
	carrier.soundBank = &soundBank;
	carrier.scale = &scale;

	//LoopCarrier loopCarrier;
	//loadCarrier(&loopCarrier);

	SAPIModulator modulatorImpl;
	modulatorImpl.Initialize(SAMPLE_RATE, WINDOW_LENGTH, NULL);

	


	OverlappingModulator overlappingModulator(&modulatorImpl, OVERLAP_LENGTH);
	//createSequence(&seqProvider, fileLen);

	Carrier* theCarrier = &carrier;
	//Carrier* theCarrier = &loopCarrier;
	//Carrier* theCarrier = &resynthCarrier;
	OverlappingCarrier overlappingCarrier(theCarrier, OVERLAP_LENGTH);
	theCarrier = &overlappingCarrier;
	//theCarrier->SetVocoderListener(&recorder);

	//Modulator* theModulator = &modulatorImpl;
	Modulator* theModulator = &overlappingModulator;

	CVocoderGUIDlg dlg;

	//vocoder.Initialize(&output, theCarrier, NULL, &recorder, NULL);
	Overlapper overlapper(OVERLAP_LENGTH);	
	vocoder.Initialize(theCarrier, &dlg, &recorder, &overlapper);

	VocoderController controller;
	dlg.controller = &controller;
	dlg.recorder = &recorder;

	PlayerThread player;
	player.Initialize(&controller, SAMPLE_RATE, WINDOW_LENGTH);

	controller.Initialize(&modulatorImpl, &dlg, &player);
	VocoderThread vocoderThread;
	vocoderThread.Initialize(theModulator, theCarrier, &vocoder, &player, &performance, WINDOW_LENGTH);

	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();

	player.Stop();
	vocoderThread.Stop();
	recorder.SaveToFiles();

	if (nResponse == IDOK)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with OK
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with Cancel
	}

	::CoUninitialize();

	performance.CalculateModulatorVocodedLag();

	return nResponse;
}

BOOL CVocoderGUIApp::InitInstance()
{
	RunVocoder();

#ifdef _DEBUG
	_CrtDumpMemoryLeaks();
#endif

	// Since the dialog has been closed, return FALSE so that we exit the
	//  application, rather than start the application's message pump.
	return FALSE;
}
